#!/usr/bin/perl -w
# Progress version of which, locate the progress program in the propath
# Author:          JustinZhang <fgz@qad.com>
# Creation Date:   2008-02-06
# Last Modified:   2008-02-06
#
use strict;
use File::Basename;
use File::Spec::Functions;
use FindBin qw($Bin);
use lib "$Bin";
use pm::File::Find;

if (scalar(@ARGV) == 0) {
    usage();
    exit(1);
}

my $program = $ARGV[0];
my $propath = $ENV{PROPATH};
if (!$propath) {
    # environment variable isn't set, read propath information from .propath
    if (-f '.propath') {
        open(PROPATH, "<.propath") or die "Can't open .propath due to:$!\n";
        while (<PROPATH>) {
            chomp;
            next if /#.*/ || /^\s*$/;
            $propath = $_;
            $propath =~ s/PROPATH=//;
            last;
        }
        close(PROPATH);
    }
    else {
        print "You must either set the PROPATH environment variable\n";
        print " or create a .propath file in current directory!\n";
        usage();
        exit 2;
    }
}

my @paths = split(/,|;|:/, $propath);
my ($prog, $package, $ext) = fileparse($program, qr/\.[^.]*/);
my @dirs = map { -d $_ ? catdir($_, $package) : $_ } @paths if $package;
my $pat = $prog . '\.[^.]*';

foreach my $p (@dirs) {
    if ($p =~ /\.pl$/ && -f $p) {
        my $ret = search_in_pl($p, $pat);
        print "$ret\@$p\n" if $ret;
    }
    else {
        my @ret = find($pat, [$p], '^CVS$|^\.svn$|^bak$', 1);
        print "$ret[0]\n" if(@ret);
    }
}

# search the program in the procedure library
# return empty string if no match found, otherwise the first matched file
sub search_in_pl{
    my($pl, $pat) = @_;
    my $cmd = join(" ",
                   "prolib",
                   $pl,
                   "-list");

    my $ret = "";
    my $file_list_begin = 0;
    open(PROLIB_OUT, "$cmd 2>&1 |") or warn "Can't run prolib: $!\n";
    while(<PROLIB_OUT>) {
        chomp;
        if (! $file_list_begin) {
            $file_list_begin = 1 if (/^Name\s+Size/);
            next; 
        }
        
        last if /^$/;

        my($file, undef) = split(/\s+/, $_, 2);
        if ($file =~ /$pat/) {
            $ret = $file;
            last;
        }
    }
    close(PROLIB_OUT);
    return $ret;
}

sub usage {

    print <<EOF
This utility search the the specified program in the propath. It will report
every matched entry in the propath including procedure library if any. Propath
can be specified either as environment variable(PROPATH) or plain-text file
(.propath) in current directory. Environment variable takes preference over
.propath file.
Usage:
    prowhich.pl program
EOF
}
